#include "LecteurSymbole.h"
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

////////////////////////////////////////////////////////////////////////////////
LecteurSymbole::LecteurSymbole(string nomFich) :
        lc(nomFich), symCour("") {
    suivant(); // pour lire le premier symbole
}

////////////////////////////////////////////////////////////////////////////////
void LecteurSymbole::suivant() {
    sauterSeparateurs();
    sauterCommentaire();
    // on est maintenant positionne sur le premier caractère d'un symbole
    ligne=lc.getLigne();
    colonne=lc.getColonne();
    //cout << "ligne : " << ligne << endl;
    symCour=Symbole(motSuivant()); // on reconstruit symCour avec le nouveau mot lu
}

////////////////////////////////////////////////////////////////////////////////
void LecteurSymbole::sauterSeparateurs() {
    while (lc.getCarCour()==' '  ||
            lc.getCarCour()=='\t' ||
            lc.getCarCour()=='\r' ||
            lc.getCarCour()=='\n')
        lc.suivant();

}

void LecteurSymbole::sauterCommentaire() {
    if (lc.getCarCour()=='#') {
        while (lc.getCarCour()!='\n') {
            lc.suivant();
        }
        lc.suivant();
        sauterSeparateurs();
        sauterCommentaire();
    }
}

////////////////////////////////////////////////////////////////////////////////
string LecteurSymbole::motSuivant() {
    static string  s;
    s="";
    if (isdigit(lc.getCarCour())) {
        // c'est le début d'un entier
        bool point = true;
        // c'est le début d'un entier
        do {
            if (lc.getCarCour()=='.') {
                point = false;
            }
            else {
                s=s+lc.getCarCour();
                lc.suivant();
            }
        } while (isdigit(lc.getCarCour()) && point);

        if (lc.getCarCour()=='.') {
            s=s+lc.getCarCour();
            lc.suivant();
            while (isdigit(lc.getCarCour())) {
                s=s+lc.getCarCour();
                lc.suivant();
            }
        }
        if (s[s.size()-1]=='.') {
            s=s+'0';
        }
    }
    else if (isOpBool(lc.getCarCour()))	{
        s=s+lc.getCarCour();
        lc.suivant();
        if (isOpBool(lc.getCarCour())) {
            s=s+lc.getCarCour();
            lc.suivant();
        }
    }
    else if (lc.getCarCour()=='"') {
        // c'est le début d'un string
        s=s+lc.getCarCour();
        lc.suivant();
        while (lc.getCarCour()!='"' && lc.getCarCour()!='\n') {
            if (lc.getCarCour() == '\\') {
                s=s+lc.getCarCour();
                lc.suivant();
                if (lc.getCarCour()=='"' && lc.getCarCour()!='\n') {
                    s=s+lc.getCarCour();
                    lc.suivant();
                }
            }
            else {
                s=s+lc.getCarCour();
                lc.suivant();
            }
        }
        if (lc.getCarCour()=='\n')
        {
            cout << "erreur ligne "<< ligne <<" : probleme string"<< endl;
            exit(-1);
        }
        s=s+lc.getCarCour(); // on ajoute le dernier guillemet
        lc.suivant();
    }
    else if (lc.getCarCour()=='\'') {
        // c'est le début d'un caract
        s=s+lc.getCarCour(); // apostraphe
        lc.suivant();
        s=s+lc.getCarCour(); // caract
        lc.suivant();
        if (lc.getCarCour()!='\'')
        {
            cout << "erreur ligne "<< ligne <<" : probleme char"<< endl;
            exit(-1);
        }
        s=s+lc.getCarCour(); // on ajoute le dernier apostrophe
        lc.suivant();
    }
    else if (isalpha(lc.getCarCour()))
        // c'est le début d'un mot
        do {
            s=s+lc.getCarCour();
            lc.suivant();
        } while (isalpha(lc.getCarCour())  ||
                 isdigit(lc.getCarCour()) ||
                 lc.getCarCour()=='_');
    else if (lc.getCarCour()!=EOF)
        // c'est un caractere special
    {
        s=lc.getCarCour();
        lc.suivant();
    }
    return s;
}

////////////////////////////////////////////////////////////////////////////////
bool LecteurSymbole::isOpBool(char c) {
    // on verifie que la chaine et entourer du char '"'
    return (c=='=' || c=='!' || c=='<' || c=='>');
}
